package com.ruoyi.fn.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.fn.domain.FinAccount;
import com.ruoyi.fn.domain.FinBudget;
import com.ruoyi.fn.domain.FinTransaction;
import com.ruoyi.fn.mapper.FinAccountMapper;
import com.ruoyi.fn.mapper.FinBudgetMapper;
import com.ruoyi.fn.mapper.FinTransactionMapper;
import com.ruoyi.fn.service.IFinTransactionService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;

/**
 * 收支记录Service业务层处理
 *
 * @author ruoyi
 * @date 2025-05-26
 */
@Service
public class FinTransactionServiceImpl implements IFinTransactionService
{
    private static final Logger log = LoggerFactory.getLogger(FinTransactionServiceImpl.class);
    @Autowired
    private FinTransactionMapper finTransactionMapper;

    @Autowired
    private FinAccountMapper finAccountMapper;

    @Autowired
    private FinBudgetMapper finBudgetMapper;
    /**
     * 查询收支记录
     *
     * @param transactionId 收支记录主键
     * @return 收支记录
     */
    @Override
    public FinTransaction selectFinTransactionByTransactionId(Long transactionId)
    {
        return finTransactionMapper.selectFinTransactionByTransactionId(transactionId);
    }

    /**
     * 查询收支记录列表
     *
     * @param finTransaction 收支记录
     * @return 收支记录
     */
    @Override
    public List<FinTransaction> selectFinTransactionList(FinTransaction finTransaction)
    {
        return finTransactionMapper.selectFinTransactionList(finTransaction);
    }

    /**
     * 新增收支记录
     *
     * @param finTransaction 收支记录
     * @return 结果
     */
    @Override
    @Transactional
    public int insertFinTransaction(FinTransaction finTransaction)
    {
        Long userId = ShiroUtils.getUserId();
        finTransaction.setUserId(userId);
        finTransaction.setCreateTime(new Date());

        int rows = finTransactionMapper.insertFinTransaction(finTransaction);
        updateAccountBalance(finTransaction);
        if ("支出".equals(finTransaction.getTransactionType())){
            updateBudgetUsedAmount(finTransaction);
        }
        return rows;
    }

    private void updateAccountBalance(FinTransaction transaction){
        FinAccount account = finAccountMapper.selectFinAccountByAccountId(transaction.getAccountId());
        if (account == null){
            throw new RuntimeException("账户不存在");
        }

        BigDecimal balance = account.getBalance();
        BigDecimal amount = transaction.getAmount();

        if ("收入".equals(transaction.getTransactionType())){
            balance = balance.add(amount);
        } else if ("支出".equals(transaction.getTransactionType())){
            balance = balance.subtract(amount);
        }
        account.setBalance(balance);
        account.setUpdateTime(new Date());
        finAccountMapper.updateFinAccount(account);
    }

    private void updateBudgetUsedAmount(FinTransaction transaction){
        Long userId = transaction.getUserId();
        Long categoryId = transaction.getCategoryId();
        LocalDate today = LocalDate.now();
        String monthStr = today.withDayOfMonth(1).toString();
        FinBudget budget = finBudgetMapper.selectByUserCategoryMonth(userId, categoryId, monthStr);
        if (budget != null){
            BigDecimal used = budget.getUsedAmount() != null ? budget.getUsedAmount() : BigDecimal.ZERO;
            used = used.add(transaction.getAmount());
            budget.setUsedAmount(used);
            budget.setUpdateTime(new Date());
            finBudgetMapper.updateFinBudget(budget);
            if (used.compareTo(budget.getBudgetAmount()) > 0){
                log.warn("【预算超支】 分类ID={}, 预算={}, 已用={}",
                        categoryId, budget.getBudgetAmount(),used);
            }
        }
    }


    /**
     * 修改收支记录
     *
     * @param finTransaction 收支记录
     * @return 结果
     */
    @Override
    public int updateFinTransaction(FinTransaction finTransaction)
    {
        finTransaction.setUpdateTime(DateUtils.getNowDate());
        return finTransactionMapper.updateFinTransaction(finTransaction);
    }

    /**
     * 批量删除收支记录
     *
     * @param transactionIds 需要删除的收支记录主键
     * @return 结果
     */
    @Override
    public int deleteFinTransactionByTransactionIds(String transactionIds)
    {
        return finTransactionMapper.deleteFinTransactionByTransactionIds(Convert.toStrArray(transactionIds));
    }

    /**
     * 删除收支记录信息
     *
     * @param transactionId 收支记录主键
     * @return 结果
     */
    @Override
    public int deleteFinTransactionByTransactionId(Long transactionId)
    {
        return finTransactionMapper.deleteFinTransactionByTransactionId(transactionId);
    }
}
